package com.common

import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.JSONArray
import com.alibaba.fastjson.JSONObject
import org.jsoup.Jsoup
import org.jsoup.safety.Whitelist
import org.springframework.core.io.ClassPathResource
import org.springframework.core.io.Resource

import java.nio.charset.StandardCharsets

/**
 * @Author Lee
 * @Description
 * @Date 2018年04月25日 20:50
 *
 */
class JsoupUtils {
    //一个白名单,里面配置允许出现的html标签,属性,特殊标签的特殊属性,强制添加的属性等等
    private static final Whitelist XSS_LIST = Whitelist.none()

    //一个白名单,准确的说是一个空的白名单,因为里面不允许出现任何html代码
    private static final Whitelist WHITELIST = Whitelist.none()

    /**
     * 过滤所有的HTML元素,一般用于过滤标题的xss代码,标题中不会允许有html代码的存在
     * @param content
     * @return
     */
    public static String cleanHTML(String content) {
        return content == null ? null : Jsoup.clean(content, WHITELIST)
    }

    /**
     * 过滤XSS字符,
     * @param content
     * @return
     */
    public static String cleanXss(String content) {
        return content == null ? null : Jsoup.clean(content, XSS_LIST)
    }

    static {
        //加载类时候读取配置的JSON文件
        Resource resource = new ClassPathResource("xss-white.json")
        try {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8))
            StringBuilder stringBuilder = new StringBuilder()
            String line = null
            while ((line = bufferedReader.readLine()) != null){
                stringBuilder.append(line.trim())
            }

            JSONObject jsonObject = JSON.parseObject(stringBuilder.toString())

            //允许标签
            JSONArray tags = jsonObject.getJSONArray("allow_tags")
            XSS_LIST.addTags(tags.toArray(new String[tags.size()]))

            //允许属性
            JSONArray properties = jsonObject.getJSONArray("allow_properties")
            XSS_LIST.addAttributes(":all",properties.toArray(new String[properties.size()]))

            //允许特殊属性
            JSONObject specialProperties = jsonObject.getJSONObject("special_properties")
            specialProperties.keySet().each {tag ->
                JSONArray attributes = specialProperties.getJSONArray(tag)
                XSS_LIST.addAttributes(tag,attributes.toArray(new String[attributes.size()]))
            }

            //允许特殊协议
            JSONObject protocols = jsonObject.getJSONObject("protocols")
            protocols.keySet().each{tag ->
                JSONObject protoObject = protocols.getJSONObject(tag)
                protoObject.keySet().each {attr ->
                    JSONArray protocolValues = protoObject.getJSONArray(attr)
                    XSS_LIST.addProtocols(tag,attr,protocolValues.toArray(new String[protocolValues.size()]))
                }
            }

            //固定属性值,非必须的
            JSONObject fixedProperties = jsonObject.getJSONObject("fixed_properties")
            if(fixedProperties != null && !fixedProperties.isEmpty()) {
                fixedProperties.keySet().each{tag ->
                    JSONObject property = fixedProperties.getJSONObject(tag)
                    if(property != null && !property.isEmpty()) {
                        property.keySet().each {attr ->
                            String value = property.getString(attr)
                            XSS_LIST.addEnforcedAttribute(tag, attr, value)
                        }
                    }
                }
            }
        } catch (e) {
            e.printStackTrace()
            throw new RuntimeException("加载XSS过滤白名单异常,请检查文件 xss-white.json")
        }
    }
}
